package com.sf.fy.global.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.sf.fy.global.service.GlobalService;
import com.sf.fy.uav.applet.IntraCityServiceClient;
import com.sf.fy.uav.applet.service.impl.OrderServiceImpl;
import com.sf.fy.uav.common.awt.JwtUtil;
import com.sf.fy.uav.common.enums.*;
import com.sf.fy.uav.common.request.order.OrderExtraRequest;
import com.sf.fy.uav.common.request.order.PrepareOrderForWebRequest;
import com.sf.fy.uav.common.utils.AddressUtils;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.MobileNumberValidatorUtil;
import com.sf.fy.uav.good.entity.TaskGoods;
import com.sf.fy.uav.good.mapper.TaskGoodsMapper;
import com.sf.fy.uav.order.controller.OrderExtraController;
import com.sf.fy.uav.order.entity.OrderInfo;
import com.sf.fy.uav.order.mapper.OrderInfoMapper;
import com.sf.fy.uav.order.service.IOrderInfoService;
import com.sf.fy.uav.task.mapper.TaskStatusLogMapper;
import com.sf.fy.uav.user.controller.UserCompanyRest;
import com.sf.fy.uav.user.entity.UserCompany;
import com.sf.fy.uav.user.mapper.UserCompanyMapper;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author ltq
 */
@Service
public class GlobalServiceImpl implements GlobalService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private TaskGoodsMapper taskGoodsMapper;


    @Autowired
    private UserCompanyRest userCompanyRest;

    @Autowired
    private IntraCityServiceClient intraCityServiceClient;


    @Autowired
    private UserCompanyMapper userCompanyMapper;

    @Autowired
    private IOrderInfoService iOrderInfoService;

    @Autowired
    private OrderExtraController orderExtraController;

    private final static Logger logger = LoggerFactory.getLogger(GlobalServiceImpl.class);

    /**
     * 校验询单入参
     */
    public void checkPlaceOrderData(PrepareOrderForWebRequest prepareOrderRequest) {
        String senderTel = prepareOrderRequest.getSenderTel();
        String receiverTel = prepareOrderRequest.getReceiverTel();
        MobileNumberValidatorUtil.checkPhone(senderTel);
        MobileNumberValidatorUtil.checkPhone(receiverTel);
        double goodsWeight = prepareOrderRequest.getGoodsWeight();
        if (goodsWeight <= 0) {
            throw new RuntimeException("货物重量不符合寄件要求");
        }
        if (goodsWeight > 9) {
            throw new RuntimeException("货物重量不符合寄件要求");
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public String placeOrderForWeb(PrepareOrderForWebRequest prepareOrderRequest) {
        System.out.println(RootContext.getXID());
        this.checkPlaceOrderData(prepareOrderRequest);
        String fromProvince = prepareOrderRequest.getFromProvince();
        String fromCity = prepareOrderRequest.getFromCity();
        String toProvince = prepareOrderRequest.getToProvince();
        String fromDistrict = prepareOrderRequest.getFromDistrict();
        String toDistrict = prepareOrderRequest.getToDistrict();
        String toCity = prepareOrderRequest.getToCity();
        if (fromProvince.contains("undefined") || fromCity.contains("undefined") || toProvince.contains("undefined") || toCity.contains("undefined")) {
            //传入的城市有问题，通过经纬度反查，比较是否同城
            String senderLat = prepareOrderRequest.getSenderLat();
            String senderLon = prepareOrderRequest.getSenderLon();
            String receiverLat = prepareOrderRequest.getReceiverLat();
            String receiverLon = prepareOrderRequest.getReceiverLon();
            Map<String, Object> stringObjectMap = AddressUtils.getLocation(senderLon, senderLat);
            Map<String, Object> stringObjectMap1 = AddressUtils.getLocation(receiverLon, receiverLat);
            fromProvince = stringObjectMap.get("province").toString();
            fromCity = stringObjectMap.get("city").toString();
            fromDistrict = stringObjectMap.get("district").toString();
            toProvince = stringObjectMap1.get("province").toString();
            toCity = stringObjectMap1.get("city").toString();
            toDistrict = stringObjectMap1.get("district").toString();
        }
        logger.info(prepareOrderRequest.toString());
        String expenseDetailsId = prepareOrderRequest.getExpenseDetailsId();
        //校验价格是否被篡改
        BigDecimal price = prepareOrderRequest.getPrice();
        BigDecimal pricePayable = null;
        if (!ObjectUtils.isEmpty(expenseDetailsId)) {
            pricePayable = iOrderInfoService.checkPrice(expenseDetailsId, price);
        }
        if (ObjectUtils.isEmpty(pricePayable)) {
            pricePayable = prepareOrderRequest.getPricePayable();
        }

        OrderInfo orderInfo = BeanUtil.copyProperties(prepareOrderRequest, OrderInfo.class);
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        String dateString = sdf.format(new Date());
        String tcWaybillNo = "FY" + dateString + UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);
        Date date = new Date();
        String userId = JwtUtil.getUserId();

        orderInfo.setOrderType(prepareOrderRequest.getProductType());
        orderInfo.setOrderStatus(OrderStatusEnum.TO_BE_PAID.getStatus());
        orderInfo.setUserId(userId);
        orderInfo.setCreateTime(date);
        orderInfo.setUpdateTime(date);
        orderInfo.setThirdPartyOrderNumber(prepareOrderRequest.getThirdPartyOrderNumber());
        orderInfo.setTcWaybillNo(tcWaybillNo);
        orderInfo.setPricePayable(pricePayable);
        orderInfo.setPricePaid(price);
        orderInfo.setPayChannel(PayChannelEnum.msp_pay.getCode());
        orderInfo.setGoodsTypeId(prepareOrderRequest.getGoodsTypeId());
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, 30);
        orderInfo.setExpireTime(c.getTime());
        orderInfo.setPlatformCode(PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode());
        iOrderInfoService.insert(orderInfo);

        //将省-市记录到order-extra表
        OrderExtraRequest orderExtraRequest = new OrderExtraRequest();
        orderExtraRequest.setCreateTime(date);
        orderExtraRequest.setUpdateTime(date);
        orderExtraRequest.setOrderId(orderInfo.getId());
        orderExtraRequest.setFromProvince(fromProvince);
        orderExtraRequest.setFromCity(fromCity);
        orderExtraRequest.setToProvince(toProvince);
        orderExtraRequest.setToCity(toCity);
        orderExtraRequest.setFromDistrict(fromDistrict);
        orderExtraRequest.setToDistrict(toDistrict);
        orderExtraController.add(orderExtraRequest);
        try {
            this.confirmPay(orderInfo.getTcWaybillNo());
            this.dealCompanyCredit(price);
        } catch (Exception e) {
            throw e;
        }
        this.dealAfterPlaceOrder(orderInfo.getId());
        return tcWaybillNo;
    }


    public void confirmPay(String outTradeNo) {
        String s = intraCityServiceClient.confirmPayForWeb(outTradeNo);
        if (!"success".equals(s)) {
            throw new RuntimeException(((JSONObject) JSONObject.parse(s)).get("msg").toString());
        }
        System.out.println(s);
    }


    private void dealCompanyCredit(BigDecimal price) {
        String userId = JwtUtil.getUserId();
        UserCompany userCompany = userCompanyRest.getByUserId(userId);
        Byte status = userCompany.getStatus();
        if (!status.equals(UserCompanyStatusEnum.NORMAL.getValue())) {
            throw new RuntimeException("公司状态异常，请联系管理员");
        }
        BigDecimal monthlyCreditLimit = userCompany.getMonthlyCreditLimit();
        BigDecimal usedCreditLimit = userCompany.getUsedCreditLimit();

        BigDecimal availableCredit = monthlyCreditLimit.subtract(usedCreditLimit);


        if (availableCredit.compareTo(price) < 0) {
            throw new RuntimeException("当前可用额度已超出，无法下单，请联系客户经理。");
        }
        userCompany.setUsedCreditLimit(userCompany.getUsedCreditLimit().add(price));
        userCompany.setUpdateTime(new Date());
        userCompanyMapper.updateById(userCompany);
    }


    @Async
    public void dealAfterPlaceOrder(String orderInfoId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderInfoId);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单不存在");
        }
        Date date = orderInfo.getCreateTime();
//        TaskStatusLog taskStatusLog = new TaskStatusLog();
//        taskStatusLog.setStatus(orderInfo.getOrderStatus());
//        taskStatusLog.setTaskId(orderInfo.getId());
//        taskStatusLog.setCreateTime(date);
//        taskStatusLog.setUpdateTime(date);
//        taskStatusLog.setUserId(orderInfo.getUserId());
//        taskStatusLogRest.add(taskStatusLog);
        TaskGoods taskGoods = new TaskGoods();
        taskGoods.setTaskId(orderInfo.getId());
        taskGoods.setGoodsTypeId(orderInfo.getGoodsTypeId());
        taskGoods.setCreateTime(date);
        taskGoods.setUpdateTime(date);
        taskGoodsMapper.insert(taskGoods);
    }
}
